#ifndef JSONMARKUPHELPER_H
#define JSONMARKUPHELPER_H

#include "FsxWsUtils_global.h"
#include "utils.h"
#include "httphelper.h"
#include <QString>
#include <QDateTime>
#include <QMap>

namespace FsxWsUtils {

//! Global settings for KML generation
/*! \sa FsxWsSettings */
struct KmlSettings {
    //! Constructor.
    KmlSettings();
    //! Constructor.
    /*! \param lineStyleColor
        \param lineStyleWidth
        \param polyStyleColor
        \param waypointModel
        \param waypointModelBaseUrl
        \param networkLinkUpdateS */
    KmlSettings(const QString &lineStyleColor, const int lineStyleWidth,
                const QString &polyStyleColor, const QString &waypointModel, const QString &waypointModelBaseUrl, const int networkLinkUpdateS);
    QString lineStyleColor; /*!< line style color */
    QString polyStyleColor; /*!< poly style color */
    QString waypointModel;  /*!< waypoint model */
    QString waypointModelBaseUrl; /*!< base URL for the model */
    int lineStyleWidth; /*!< line style width */
    int networkLinkUpdatePeriodS; /*!< if networklink, update time [s] */
    //! URL of waypoint model
    /*! \return URL */
    QString getWaypointModelUrl() const { return HttpHelper::appendToUrl(KmlSettings::waypointModelBaseUrl, KmlSettings::waypointModel); }
};

//! Parameters for JSON methods.
struct JsonParameter
{
    //! Constructor, init default values.
    JsonParameter();
    //! Constructor.
    /*! \param id
        \param withWaypoints
        \param resolutionPeriodMs */
    JsonParameter(int id, bool withWaypoints, qint64 resolutionPeriodMs);
    int id; /*!< selected aircraft id (or all) */
    bool withWaypoints; /*!< include waypoints? */
    qint64 waypointResolutionPeriodMs; /*!< waypoint resolution */
};

//! Parameters for KML methods
/*! \sa KmlSettings */
struct KmlParameter
{
    //! Constructor.
    KmlParameter();
    //! Constructor.
    /*! \param id
        \param modelUrl
        \param networkLinkUpdatePeriodS
        \param resolutionPeriodMs
        \param maxNumberWaypoints
        \param waypointTitle
        \param waypointFurtherInfo */
    KmlParameter(int id, const QString &modelUrl, int networkLinkUpdatePeriodS, qint64 resolutionPeriodMs = -1, int maxNumberWaypoints = -1, const QString &waypointTitle = "", const QString &waypointFurtherInfo = "");
    //! By other parameter
    /*! \param otherParameter */
    KmlParameter(const KmlParameter &otherParameter);
    //! By KML settings.
    /*! \param kmlSettings */
    KmlParameter(const KmlSettings &kmlSettings);
    int id; /*!< selected aircraft id (or all) */
    QString modelUrl; /*!< model URL */
    QString waypointTitle; /*!< title of the waypoint */
    QString waypointFurtherInfo;  /*!< further info about the waypoint */
    int networkLinkUpdatePeriodS; /*!< update period of a network link element [s] */
    qint64 waypointResolutionPeriodMs; /*!< waypoint resolution [ms] */
    int maxNumberWaypoints; /*!< max. number of waypoints */
};

//! Helper class for JSON, and Google KML
class JsonMarkupHelper
{
private:
    static QMap<int, QString> _indents; /*!< map indention level to string */
public:
    static KmlSettings Settings; /*!< corresponding settings */
    static const QString Indent; /*!< Indentions string */
    //! Indention string for level
    /*! \param level indention
        \return indention */
    static const QString Indention(const int level);
    static const QString KmlAltModeAbsolute; /*!< KML string */
    static const QString KmlDocSchema; /*!< KML string */
    //! KML orientation.
    /*! \param level
        \param headingDeg
        \param tiltDeg pitch
        \param rollDeg bank
        \return formatted KML String */
    static const QString kmlOrientation(const int level, const double headingDeg, const double tiltDeg = 0, const double rollDeg = 0);
    //! KML location.
    /*! \param level
        \param lat
        \param lng
        \param altM [meters]
        \return formatted KML String */
    static const QString kmlLocation(const int level, const double lat, const double lng, const double altM);
    //! KML coordinates.
    /*! \param level
        \param lat
        \param lng
        \param altM [meters]
        \return formatted KML String */
    static const QString kmlCoordinates(const int level, const double lat, const double lng, const double altM);
    //! KML scale.
    /*! \param level
        \param scaleX
        \param scaleY
        \param scaleZ
        \return formatted KML String */
    static const QString kmlScale(const int level, const double scaleX = 1, const double scaleY = 1, const double scaleZ = 1);
    //! Wrap KML string into document tags.
    /*! \param level
        \param innerKml
        \param docName
        \return formatted KML String */
    static const QString kmlWrapInDocument(const int level, const QString &innerKml, const QString &docName);
    //! KML look at.
    /*! \param level
        \param lat
        \param lng
        \param altM
        \param headingDeg
        \param tiltDeg pitch
        \param rollDeg bank
        \return formatted KML String */
    static const QString kmlLookAt(const int level, const double lat, const double lng, const double altM, const double headingDeg = 0, const double tiltDeg = 0, const double rollDeg = 0);
    //! KML icon.
    /*! \param level
        \param colour
        \param iconUrl
        \param iconScale
        \return formatted KML String */
    static const QString kmlIconStyle(const int level, const QString &colour, const QString &iconUrl, const double iconScale);
    //! KML placemark.
    /*! \param level
        \param id
        \param iconUrl
        \param iconScale
        \param labelScale
        \return formatted KML String */
    static const QString kmlPlacemarkStyle(const int level, const QString &id, const QString &iconUrl, const double iconScale, const double labelScale);
    //! KML label style.
    /*! \param level
        \param colour
        \param labelScale
        \return formatted KML String */
    static const QString kmlLabelStyle(const int level, const QString &colour, const double labelScale);
    //! KML style map.
    /*! \param level
        \param styleMapId
        \param styleMapNormal
        \param styleMapHighlight
        \return formatted KML String */
    static const QString kmlStyleMap(const int level, const QString &styleMapId, const QString &styleMapNormal, const QString &styleMapHighlight);
    //! KML line style.
    /*! \param level
        \return formatted KML String */
    static const QString kmlLineStyle(const int level);
    //! KML poly style.
    /*! \param level
        \return formatted KML String */
    static const QString kmlPolyStyle(const int level);
    //! KML refreshing network link.
    /*! \param level
        \param url
        \param refreshTimeS
        \return formatted KML String */
    static const QString kmlNetworkLinkRefresh(const int level, const QString &url, const int refreshTimeS);
    //! KML document with refreshing network link.
    /*! \param url
        \param networkLinkName
        \param refreshTimeS
        \return formatted KML String */
    static const QString kmlNetworkLinkDocument(const QString &url, const QString &networkLinkName = "Refreshing KML document", const int refreshTimeS = 60);
    //! KML date and time.
    /*! \param timestamp
        \param utc
        \return formatted KML String */
    static const QString kmlDateTime(const qint64 timestamp = 0, const bool utc = true);
    //! KML network link control.
    /*! \param level
        \param refreshOffsetMs
        \param lookAtOrCamera
        \return formatted KML String */
    static const QString kmlNetworkLinkControl(const int level, const int refreshOffsetMs, const QString &lookAtOrCamera = "");
    //! Wrap Javascript /JSON string into JS function.
    /*! \param level
        \param functionName
        \param innerJson
        \return formatted JSON String */
    static const QString jsonWrapInJsFunctionCall(const int level, const QString &functionName, const QString &innerJson);
};
}
#endif // JSONMARKUPHELPER_H
